package info.niwota.ziplock;

import java.io.File;
import java.util.ArrayList;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.Toast;

public class ZipImportActivity extends ListActivity implements OnClickListener {
	
	private class ImportTask extends AsyncTask<Void, Void, Void> {
		boolean delete;

		public ImportTask(boolean del) {
			this.delete = del;
		}

		@Override
		protected Void doInBackground(Void... params) {
			try {
				importZip(delete);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onCancelled() {
			dismissDialog(DIALOG_PROGRESS);
		}

		@Override
		protected void onPostExecute(Void result) {
			try {
				//
				setResult(RESULT_OK);
				finish();
			} finally {
				dismissDialog(DIALOG_PROGRESS);
			}
		}

		@Override
		protected void onPreExecute() {
			showDialog(DIALOG_PROGRESS);
		}
	}

	private class InitTask extends AsyncTask<Void, Void, Void> {

		private Exception error;

		@Override
		protected Void doInBackground(Void... params) {
			try {
				statusMonitor.aborted = false;
				statusMonitor.handler = progressHandler;
				//
				FileUtils.findZip(top, statusMonitor, files);
			} catch (Exception e) {
				error = e;
			}
			return null;
		}

		@Override
		protected void onCancelled() {
			dismissDialog(DIALOG_PROGRESS);
		}

		@Override
		protected void onPostExecute(Void result) {
			if (error != null) {
				showMessage(""+error.getMessage());
			}
			try {
				updateUi();
			} finally {
				dismissDialog(DIALOG_PROGRESS);
			}
		}

		@Override
		protected void onPreExecute() {
			showDialog(DIALOG_PROGRESS);
			// setProgressBarIndeterminateVisibility(true);
		}
	}

	private static final int DIALOG_IMPORT = 1;

	private static final int DIALOG_PROGRESS = 2;

	private static final String TAG = "ZipImportActivity";

	private final static File top = Environment.getExternalStorageDirectory();

	private ArrayAdapter<File> adapter;

	private Button btnCancel;

	private Button btnOk;

	private ArrayList<File> files = new ArrayList<File>();

	private ArrayList<File> list;
	
	private ProgressDialog progressDialog;

	private Handler progressHandler = new Handler() {

		public void handleMessage(Message msg) {
			CharSequence m = statusMonitor.message;
			if (Debug.DEBUG) {
				Log.d(TAG, "message: " + m);
			}
			progressDialog.setTitle(m);

		}
		
	};

	private StatusMonitor statusMonitor = new StatusMonitor();

	private ArrayAdapter<NameIndex> viewSelectedItems;;

	private Dialog createImportDialog() {
		final AlertDialog.Builder b = new AlertDialog.Builder(this);
		LayoutInflater f = LayoutInflater.from(this);
		final View v = f.inflate(R.layout.dia_import, null);
		b.setTitle(R.string.action_import);
		b.setView(v);
		viewSelectedItems = new ArrayAdapter<NameIndex>(this,
				R.layout.index_dialog_item);
		b.setAdapter(viewSelectedItems, null);
		b.setPositiveButton(getString(R.string.button_ok),
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						CheckBox ck = (CheckBox) v
								.findViewById(R.id.import_delete_orig);
						boolean del = ck.isChecked();
						doImport(del);
					}
				});
		b.setNegativeButton(getString(R.string.button_cancel), null);
		b.setCancelable(true);
		final AlertDialog d = b.create();
		return d;
	}

	public ProgressDialog createProgressDialog() {
		final Context ctx = this;
		ProgressDialog pd = new ProgressDialog(ctx);
		pd.setTitle(top.getPath());
		pd.setMessage(ctx.getText(R.string.wait));
		pd.setIndeterminate(true);
		pd.setCancelable(true);
		DialogInterface.OnClickListener l =  new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				statusMonitor.aborted = true;
				//
				doCancel();
			}
		};
		pd.setButton(ProgressDialog.BUTTON_POSITIVE,
				getString(R.string.button_cancel), l);
		return pd;
	}

	private void doCancel() {
		setResult(RESULT_CANCELED);
		finish();
	}

	private void doImport(boolean del) {
		ImportTask task = new ImportTask(del);
		task.execute();
	}

	private int getCount() {
		return adapter.getCount();
	}

	private int getSelectedCount() {
		SparseBooleanArray ps = getListView().getCheckedItemPositions();
		int size = adapter.getCount();
		int cnt = 0;
		for (int i = 0; i < size; i++) {
			if (ps.get(i)) {
				cnt++;
			}
		}
		return cnt;
	}

	private ArrayList<File> getSelectedItems() {
		SparseBooleanArray ps = getListView().getCheckedItemPositions();
		ArrayList<File> ck = new ArrayList<File>();
		int size = adapter.getCount();
		for (int i = 0; i < size; i++) {
			if (ps.get(i)) {
				ck.add(adapter.getItem(i));
			}
		}
		return ck;
	}

	private void importZip(boolean delete) {
		ArrayList<File> zips = getSelectedItems();
		FileUtils.importZip(this, zips, delete);
	}

	private void init() {
		try {
			files.clear();
			list = null;
			viewSelectedItems = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	}

	public void onClick(View v) {
		int id = v.getId();
		switch (id) {
		case R.id.button_ok:
			showDialog(DIALOG_IMPORT);
			break;
		case R.id.button_cancel:
			doCancel();
			break;
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (Debug.DEBUG) {
			Log.d(TAG, "onCreate: " + savedInstanceState);
		}
		//
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		//requestWindowFeature(Window.FEATURE_LEFT_ICON);
		setContentView(R.layout.zip_import);
		//
		adapter = new ArrayAdapter<File>(this, R.layout.zip_import_item, files);

		setProgressBarIndeterminate(true);
		//
		final ListView lv = getListView();
		lv.setAdapter(adapter);
		lv.setItemsCanFocus(false);
		lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		//
		setTitle(R.string.action_import);
		//getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
		//		R.drawable.icon25);
		//
		View buttons = findViewById(R.id.buttons);
		buttons.setVisibility(View.VISIBLE);
		btnOk = (Button) findViewById(R.id.button_ok);
		btnCancel = (Button) findViewById(R.id.button_cancel);
		btnOk.setOnClickListener(this);
		btnCancel.setOnClickListener(this);
		
		//
		init();

		if (savedInstanceState != null) {
			restore();
			updateUi();
		} else {
			new InitTask().execute();
		}
		//
		if (Debug.DEBUG) {
			Log.d(TAG, " onCraete");
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_IMPORT:
			return createImportDialog();
		case DIALOG_PROGRESS:
			progressDialog = createProgressDialog();
			return progressDialog;
		default:
		}
		return null;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		return false;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			doCancel();
			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		int sc = getSelectedCount();
		updateTitle(sc);
		showOrHideActions(sc > 0);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		return false;
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
		case DIALOG_IMPORT: {
			viewSelectedItems.clear();
			SparseBooleanArray ps = getListView().getCheckedItemPositions();
			int size = adapter.getCount();
			for (int i = 0; i < size; i++) {
				if (ps.get(i)) {
					File f = adapter.getItem(i);
					NameIndex ni = new NameIndex();
					ni.name = f.toString();
					ni.pos = i;
					viewSelectedItems.add(ni);
				}
			}
			break;
		}
		case DIALOG_PROGRESS:
			progressDialog.setTitle(top.getPath());
			break;
		}
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		return false;
	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		Object[] obj = new Object[3];
		obj[0] = getTitle();
		obj[1] = getSelectedItems();
		obj[2] = files;
		return obj;
	}

	private void refreshUi(ListView v) {
		int sc = getSelectedCount();
		updateTitle(sc);
		showOrHideActions(sc > 0);
		v.requestLayout();
	}

	@SuppressWarnings("unchecked")
	private void restore() {
		Object[] obj = (Object[]) getLastNonConfigurationInstance();
		String title = (String) obj[0];
		setTitle(title);
		ArrayList<File> il = (ArrayList<File>) obj[1];
		list = il;
		ArrayList<File> al = (ArrayList<File>) obj[2];
		if (al != null) {
			files.addAll(al);
		}
	}

	void showMessage(String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
	}

	private void showOrHideActions(boolean b) {
		btnOk.setEnabled(b);
	}

	private void updateTitle(int sc) {
		int tc = getCount();
		String t = (tc > 0 ? getString(R.string.title_import_found, sc, tc)
				: getString(R.string.title_import_not_found));
		setTitle(t);
	}

	private void updateUi() {
		// set to reload
		getListView().setAdapter(adapter);
		//
		ListView v = getListView();
		v.clearChoices();
		//
		if (list != null) {
			File[] el = list.toArray(new File[0]);
			int pos = 0;
			for (File a : files) {
				boolean ck = false;
				if (el != null) {
					for (int i = 0; i < el.length; i++) {
						if (el[i].equals(a)) {
							ck = true;
							break;
						}
					}
				}
				v.setItemChecked(pos++, ck);
			}
		}
		//
		refreshUi(v);
	}
}
